#include <fstream>
#include <iomanip>
#include <iostream>
#include <vector>

using namespace std;

#define HISTOGRAM_MIN 0.000
#define HISTOGRAM_MAX 0.100
#define HISTOGRAM_DELTA 0.001
#define MINIMUM_COUNT 100

int main(int argc, const char* argv[])
{
     // read data
     cerr << "Reading data..." << endl;
     double value, prev_value;
     int count = 0;
     // create histogram
     int histogramSize = (int) ((HISTOGRAM_MAX - HISTOGRAM_MIN)/HISTOGRAM_DELTA);
     vector< vector<unsigned long long> > h;
     vector<unsigned long long> losses;
     vector<unsigned long long> tries;
     // first set correct size
     h.resize(histogramSize+1);
     for (unsigned int j = 0; j < histogramSize + 1; j++)
	  h[j].resize(histogramSize, 0);
     losses.resize(histogramSize+1, 0);
     tries.resize(histogramSize+1,0);
     // iterate over samples
     int prev_state;
     int state;
     while (!cin.eof())
     {
	  count++;
	  cin >> value;
	  if (cin.fail() && !cin.eof())
	  {
	       cerr  << "Failed to read " << count << "-th value" << endl;
	       return -1;
	  }
	  if (count == 1)
	  {
	       prev_state = (int) ((value+HISTOGRAM_DELTA/2.0)/HISTOGRAM_DELTA);
	       prev_state = prev_state < histogramSize ? prev_state : histogramSize - 1;
	       prev_state = prev_state < 0 ? 0 : prev_state;
	       continue;
	  }
	  state = (int) ((value+HISTOGRAM_DELTA/2.0)/HISTOGRAM_DELTA);
	  state = state < histogramSize ? state : histogramSize - 1;
	  state = state < 0 ? 0 : state;
	  // proper delay - no loss
	  if (value >= 0.0)
	  {
	       h[prev_state][state]++;
	       tries[prev_state]++;
	  }
	  // lost packet
	  else
	  {
	       state = histogramSize - 1;
	       losses[prev_state]++;
	       tries[prev_state]++;
	  }
	  prev_state = state;
     }
     // filter out distributions with low counts
     for (unsigned int j = 0; j < histogramSize; j++)
     {
	  unsigned long long entries_count = 0;
	  for (unsigned int k = 0; k < histogramSize; k++)
	  {
	       entries_count += h[j][k];
	  }
	  if (entries_count < MINIMUM_COUNT)
	  {
	       // remove j-th entry from all other rows
	       for (unsigned int k = 0; k < histogramSize + 1; k++)
	       {
		    tries[k] -= h[k][j];
		    h[k][j] = 0;
	       }
	       // clear j-th row
	       for (unsigned int k = 0; k < histogramSize; k++)
	       {
		    tries[j] = 0;
		    losses[j] = 0;
		    h[j][k] = 0;
	       }
	  }
     }
     int table_total = 0;
     for (unsigned int j = 0; j < histogramSize + 1; j++)
     {
	  int entries_count = 0;
	  unsigned long long t = 0xffffffff;
	  for (unsigned int k = 0; k < histogramSize; k++)
	  {
	       if (h[j][k]>0)
		    entries_count++;
	  }
	  if (entries_count == 0)
	       continue;
	  table_total++;
     }
     // print out in empath format
     int lowest_table = histogramSize;
     int table_number = 0;
     cout << "# number of tables" << endl;
     cout << table_total << endl;
     for (unsigned int j = 0; j < histogramSize + 1; j++)
     {
	  int entries_count = 0;
	  unsigned long long t = 0xffffffff;
	  for (unsigned int k = 0; k < histogramSize; k++)
	  {
	       if (h[j][k]>0)
		    entries_count++;
	  }
	  if (entries_count == 0)
	       continue;
	  lowest_table = j < lowest_table ? j : lowest_table;
	  cout << "# table #" << table_number << " number_of_entries loss" << endl;
	  table_number++;
	  cout << entries_count << " ";
	  t = (double) losses[j] / (double) tries[j] * (double) t;
	  cout << "0x" << hex << setw(8) << setfill('0') << t << dec << endl;
	  unsigned long long sum = 0;
	  cout << "# x y_max next_table" << endl;
	  for (unsigned int k = 0; k < histogramSize; k++)
	  {
	       if (h[j][k] > 0)
	       {
		    sum += h[j][k];
		    t = 0xffffffff;
		    cout << (int)(k*HISTOGRAM_DELTA*1e6) << " ";
		    t = (unsigned long long)( (double)sum/(double)(tries[j]-losses[j])
			  * (double)(t+1) );
		    t -= 1;
		    cout << "0x" << hex << setw(8) << setfill('0') << ((unsigned long) t) << dec << " ";
		    cout << (k-lowest_table) << endl;
	       }
	  }

	  cout << endl;
     }
     return 0;
}
